/*
	消息封包/拆包实现
	|datalen|msgid|data|
	|4字节	 |4字节 |datalen字节|
	|		Head(8字节)		|	 Data(Datalen字节)		|
*/

package zserver

import (
	"bytes"
	"encoding/binary"
	"errors"
	"zinx/utils"
	"zinx/zinterface"
)

type ZDataPack struct{}

func NewDataPack() zinterface.IDataPack {
	return &ZDataPack{}
}

// 获取消息头长度，固定8个字节
func (zdp *ZDataPack) GetHeadLength() uint32 {
	return 8
}

// 封包方法
func (zdp *ZDataPack) Pack(msg zinterface.IMessage) ([]byte, error) {
	// 创建buf
	databuf := bytes.NewBuffer([]byte{})

	// 写入datalen
	if err := binary.Write(databuf, binary.LittleEndian, msg.GetMsgLength()); err != nil {
		return nil, err
	}

	// 写入msgid
	if err := binary.Write(databuf, binary.LittleEndian, msg.GetMsgId()); err != nil {
		return nil, err
	}

	// 写入Data
	if err := binary.Write(databuf, binary.LittleEndian, msg.GetMsgData()); err != nil {
		return nil, err
	}

	return databuf.Bytes(), nil
}

// 拆包方法
func (zdp *ZDataPack) UnPack(binaryData []byte) (zinterface.IMessage, error) {
	databuf := bytes.NewReader(binaryData)

	// 新建msg
	msg := &ZMessage{}

	// 读取datalen
	if err := binary.Read(databuf, binary.LittleEndian, &msg.MsgLength); err != nil {
		return nil, err
	}

	// 读取msgid
	if err := binary.Read(databuf, binary.LittleEndian, &msg.MsgId); err != nil {
		return nil, err
	}

	// 判断长度是否超出最大限制
	if utils.GlobalObject.MaxPackageSize > 0 && msg.MsgLength > uint32(utils.GlobalObject.MaxPackageSize) {
		return nil, errors.New("unpack error: Too Large Package")
	}

	return msg, nil
}